﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace AD_ImageLoader
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("\nImport Photos to Active Directory");
            Console.WriteLine("---------------------------------");
            Console.WriteLine("USAGE:");
            Console.WriteLine("AD_ImageLoader.exe [-s]");
            Console.WriteLine("-s : Supresses the pause at the end of processing.");
            Console.WriteLine("---------------------------------");

            // Get the current location of the EXE
            string location = System.Reflection.Assembly.GetExecutingAssembly().Location;

            // Get the folder location
            var asmLocation = new System.IO.DirectoryInfo(location);
            var dirLocation = asmLocation.Parent;

            // Create folders for the photos (if req.) and set a reference.
            var processedLocation = dirLocation.CreateSubdirectory("Processed");
            var sourceLocation = dirLocation.CreateSubdirectory("Source");

            // Process each photo in the Source folder.
            foreach (FileInfo file in sourceLocation.EnumerateFiles())
            {
                Console.WriteLine(string.Format("Photo: {0}", file.ToString()));
                
                // Extract the username from the file name.
                // ie. jkent.jpg = jkent
                var userName = (file.ToString().Replace(file.Extension, ""));
                var fileName = file.FullName;

                Console.WriteLine(string.Format("Username: {0}", userName));

                // Load the Image into Active Directory
                var ret = LoadImageIntoAD(userName, fileName);

                // If successful, move the file into the Processed folder
                if (ret == true)
                {
                    try
                    {
                        file.CopyTo(processedLocation.FullName + @"\" + file.Name, true);
                        file.Delete();
                    }
                    catch (UnauthorizedAccessException)
                    {
                        Console.WriteLine("ERROR: You do not have permission to move images into the Processed folder.");
                    }
                }
                else
                    Console.WriteLine("Import Failed");

                Console.WriteLine("---------------------------------");
            }

            if (args.Length == 0)
            {
                Console.WriteLine("\nPress any key to continue...");
                Console.Read();
            }

            return;
        }

        static bool LoadImageIntoAD(string userName, string fileName)
        {
            // Determine the current domain
            string domain = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain().Name;

            // Get the LDAP Distinguished Name from the SAM / username
            string dn = GetUserDistinguishedName(userName);

            Console.WriteLine(string.Format("Distinguished Name: {0}", dn));

            if (dn != null)
            {
                // Load the photo into memory
                byte[] data = File.ReadAllBytes(fileName);

                // Get the user object from AD
                var de = new DirectoryEntry("LDAP://" + domain + "/" + dn);

                if (de != null)
                {
                    Console.WriteLine("Directory Entry: Found");

                    // Clear any existing photos
                    de.Properties["jpegPhoto"].Clear();
                    de.Properties["thumbnailPhoto"].Clear();

                    // Add the photo to the user AD object.
                    de.Properties["jpegPhoto"].Add(data);
                    de.Properties["thumbnailPhoto"].Add(data);

                    // Update AD
                    de.CommitChanges();

                    Console.WriteLine("Directory Entry: Updated");

                    return true;
                }
                else
                    Console.WriteLine("Directory Entry: Not Found");
            }
            else
                Console.WriteLine("Distinguished Name: Not Found");

            return false;
        }

        static string GetUserDistinguishedName(string userName)
        {
            // Get the Domain Pricipal
            PrincipalContext insPrincipalContext = new PrincipalContext(ContextType.Domain);

            // Get the User Principal and filter it by SAM / username
            UserPrincipal insUserPrincipal = new UserPrincipal(insPrincipalContext);
            insUserPrincipal.SamAccountName = userName;

            // Execute search.
            PrincipalSearcher insPrincipalSearcher = new PrincipalSearcher();
            insPrincipalSearcher.QueryFilter = insUserPrincipal;
            PrincipalSearchResult<Principal> results = insPrincipalSearcher.FindAll();

            foreach (Principal p in results)
            {
                // Return the first record.
                return p.DistinguishedName;
                
            }

            return null;
        }
    }
}
